﻿using System;
using System.Collections.Generic;
using System.Text;
using ACompany.OrderProcessing.Model;
using ACompany.OrderProcessing.NHibernateRepository;

namespace ACompany.OrderProcessing.Services
{
    public class ProductService : IProductService
    {
        private readonly IProductRepository _productRepository;
        private readonly IOrderRepository _orderRepository;

        #region Ctors
        public ProductService()
            : this(new ProductRepository(), new OrderRepository())
        {
        }
        public ProductService(IProductRepository productRepository, IOrderRepository orderRepository)
        {
            _productRepository = productRepository;
            _orderRepository = orderRepository;
        }
        #endregion

        public void Save(Product product)
        {
            if (product.GetBrokenRules().Count == 0)
            {
                _productRepository.Save(product);
            }
            else
            {
                throw new InvalidOperationException(string.Format("the product cannot be saved in this state {0}", BuildErrorListFrom(product)));
            }

        }

        private string BuildErrorListFrom(Product product)
        {
            var sb = new StringBuilder();
            foreach (var brokenRule in product.GetBrokenRules())
            {
                sb.AppendLine(brokenRule.Rule);
            }
            return sb.ToString();
        }

        public void Remove(Product product)
        {
            if (CanRemove(product))
                _productRepository.Remove(product);
            else
            {
                throw new ApplicationException("this product cannot be removed and it is linked to orders");
            }
        }

        private bool CanRemove(Product product)
        {
            return _orderRepository.FindAllOrdersContainingProductby(product.Id).Count == 0;
        }

        public Product FindBy(Guid id)
        {
            return _productRepository.FindBy(id);
        }

        public IList<Product> FindAll()
        {
            return _productRepository.FindAll();
        }
    }
}
